﻿#include "FITKAbaqusHDF5AdaptorStep.h"
#include "FITK_Interface/FITKInterfaceIOHDF5/FITKInterfaceHDF5AdaptorBoundaryLocation.h"

#include "FITK_Kernel/FITKCore/FITKVec3D.h"
#include "FITK_Kernel/FITKCore/FITKEnumTransformer.hpp"

#include "FITK_Interface/FITKInterfaceIO/FITKAbstractHDF5Reader.h"
#include "FITK_Interface/FITKInterfaceIO/FITKAbstractHDF5Writer.h"

#include "FITK_Interface/FITKInterfaceModel/FITKComponentManager.h"
#include "FITK_Interface/FITKInterfaceModel/FITKUnstructuredMesh.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKBoundaryLocation.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAssembly.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMeshPartVTK.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepInit.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepFrequency.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepGeneralStatic.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepDynamicExplicit.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBoundaryConditionManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAbstractLoad.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadConcentratedForce.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadPressure.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadMoment.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadBodyForce.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadGravity.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAbstractBoundaryCondition.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBoundaryConditionDisplacement.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBoundaryConditionSymmetry.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaFieldOutput.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaHistoryOutput.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaFieldOutputManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaHistoryOutputManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInteractionSurfToSurfExplicit.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInteractionGeneralContactExplicit.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInteractionManager.h"

#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"

namespace IO
{
    QString FITKAbaqusHDF5AdaptorStep::getAdaptorClass()
    {
        return "FITKAbaqusHDF5AdaptorStep";
    }

    bool FITKAbaqusHDF5AdaptorStep::adaptR()
    {
        auto step = dynamic_cast<Interface::FITKAbaAbstractStep*>(_dataObj);
        if (!_reader || !step || !_h5Group) return false;
        bool isR = true;
        isR &= readStep(step, *_h5Group);
        return isR;
    }

    bool FITKAbaqusHDF5AdaptorStep::adaptW()
    {
        auto step = dynamic_cast<Interface::FITKAbaAbstractStep*>(_dataObj);
        if (!_writer || !step || !_h5Group) return false;
        bool isW = true;
        isW &= writeStep(step, *_h5Group);
        return isW;
    }

    bool FITKAbaqusHDF5AdaptorStep::readStep(Interface::FITKAbaAbstractStep* step, H5::Group& h5Group)
    {
        if (!step) return false;
        bool isR = true;

        isR &= readNDataObject(step, h5Group);
        //分析步类型
        auto stepType = step->getStepType();
        //分析步描述
        auto Decription = readStrAttribute(h5Group, "Decription");
        step->setDescription(QString::fromStdString(Decription));
        //几何非线性状态
        bool Nlgeom = readBoolAttribute(h5Group, "Nlgeom");
        step->setNlgeom(Nlgeom);
        //分析步时间
        bool Time = readDoubleAttribute(h5Group, "Time");
        step->setTime(Time);
        //是否激活
        bool Active = readBoolAttribute(h5Group, "Active");
        step->setActive(Active);
        //获取重启动写出频率
        int RestartWriteFrequency = readIntAttribute(h5Group, "RestartWriteFrequency");
        step->setRestartWritFrequency(RestartWriteFrequency);
        //重启动写出间隔数目
        int RestartWriteIntervals = readIntAttribute(h5Group, "RestartWriteIntervals");
        step->setRestartWriteIntervals(RestartWriteIntervals);
        //重启动写出是否覆盖
        bool OverlayState = readDoubleAttribute(h5Group, "OverlayState");
        step->setOverlayState(OverlayState);
        //重启动写出时间标记
        bool TimeMarkState = readDoubleAttribute(h5Group, "TimeMarkState");
        step->setTimeMarkState(TimeMarkState);

        if (stepType == Interface::FITKAbaAbstractStep::FITKAbaStepType::GeneralStatic)
        {
            isR &= readStatic(step, h5Group);
        }
        else if (stepType == Interface::FITKAbaAbstractStep::FITKAbaStepType::DynamicExplicit)
        {
            isR &= readDynamic(step, h5Group);
        }
        else if (stepType == Interface::FITKAbaAbstractStep::FITKAbaStepType::Frequency)
        {
            isR &= readFrequency(step, h5Group);
        }
        else if (stepType == Interface::FITKAbaAbstractStep::FITKAbaStepType::Init)
        {

        }
        else
        {
            return false;
        }
        return isR;
    }

    bool FITKAbaqusHDF5AdaptorStep::readStatic(Interface::FITKAbaAbstractStep* step, H5::Group& h5Group)
    {
        auto generalStetic = dynamic_cast<Interface::FITKAbaStepGeneralStatic*>(step);
        if (!generalStetic || h5Group.getLocId() == -1) return false;
        bool isValid = false;

        //时间增量步类型
        auto sIncrementType = readStrAttribute(h5Group, "IncrementType");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::TimeIncrementType> fitkTITypeTrafer;
        auto eIncrementType = fitkTITypeTrafer.fromString(QString::fromStdString(sIncrementType), isValid);
        if (!isValid) return false;
        generalStetic->setIncrementType(eIncrementType);
        //最大时间增量步数目
        int MaximumNumberOfIncrements = readIntAttribute(h5Group, "MaximumNumberOfIncrements");
        generalStetic->setMaximumNumberOfIncrements(MaximumNumberOfIncrements);
        //获取初始时间增量步大小
        double InitIncrementSize = readDoubleAttribute(h5Group, "InitIncrementSize");
        generalStetic->setInitIncrementSize(InitIncrementSize);
        //最小时间增量步大小
        double MinIncrementSize = readDoubleAttribute(h5Group, "MinIncrementSize");
        generalStetic->setMinIncrementSize(MinIncrementSize);
        //最大时间增量步大小
        double MaxIncrementSize = readDoubleAttribute(h5Group, "MaxIncrementSize");
        generalStetic->setMaxIncrementSize(MaxIncrementSize);
        //固定时间增量步大小
        double FixedIncrementSize = readDoubleAttribute(h5Group, "FixedIncrementSize");
        generalStetic->setFixedIncrementSize(FixedIncrementSize);

        return true;
    }

    bool FITKAbaqusHDF5AdaptorStep::readDynamic(Interface::FITKAbaAbstractStep* step, H5::Group& h5Group)
    {
        auto dynamic = dynamic_cast<Interface::FITKAbaStepDynamicExplicit*>(step);
        if (!dynamic) return false;
        bool isR = true;
        bool isValid = false;
        //包括绝热效应
        bool IncludeAdiabaticHeatingEffects = readBoolAttribute(h5Group, "IncludeAdiabaticHeatingEffects");
        dynamic->setIncludeAdiabaticHeatingEffects(IncludeAdiabaticHeatingEffects);
        //时间增量步类型，自动或固定
        auto sIncrementType = readStrAttribute(h5Group, "IncrementType");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::TimeIncrementType> fitkTITypeTrafer;
        auto eIncrementType = fitkTITypeTrafer.fromString(QString::fromStdString(sIncrementType), isValid);
        if (!isValid) return false;
        dynamic->setIncrementType(eIncrementType);
        //稳定时间增量步估计类型，全局或单元by单元
        auto sStableIncrementEstimatorType = readStrAttribute(h5Group, "StableIncrementEstimatorType");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::StableIncrementEstimator> fitkSIETypeTrafer;
        auto eStableIncrementEstimatorType = fitkSIETypeTrafer.fromString(QString::fromStdString(sStableIncrementEstimatorType), isValid);
        if (!isValid) return false;
        dynamic->setStableIncrementEstimator(eStableIncrementEstimatorType);
        //improve Dt method状态
        bool ImproveDtMethod = readBoolAttribute(h5Group, "ImproveDtMethod");
        dynamic->setImproveDtMethod(ImproveDtMethod);
        //最大时间增量步类型，无限制或通过指定值控制
        auto sMaxTimeIncrementType = readStrAttribute(h5Group, "MaxTimeIncrementType");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::MaxTimeIncrement> fitkMTITypeTrafer;
        auto eMaxTimeIncrementType = fitkMTITypeTrafer.fromString(QString::fromStdString(sMaxTimeIncrementType), isValid);
        if (!isValid) return false;
        dynamic->setMaxTimeIncrement(eMaxTimeIncrementType);
        //最大时间增量步，当通过指定值控制时有效
        double MaxTimeIncrementValue = readDoubleAttribute(h5Group, "MaxTimeIncrementValue");
        dynamic->setMaxTimeIncrementValue(MaxTimeIncrementValue);
        //时间缩放系数
        double TimeScalingFactor = readDoubleAttribute(h5Group, "TimeScalingFactor");
        dynamic->setTimeScalingFactor(TimeScalingFactor);
        //增量步定义方式
        auto sIncrementSizeSelectionType = readStrAttribute(h5Group, "IncrementSizeSelectionType");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::IncrementSizeSelection> fitkISSTypeTrafer;
        auto eIncrementSizeSelectionType = fitkISSTypeTrafer.fromString(QString::fromStdString(sIncrementSizeSelectionType), isValid);
        if (!isValid) return false;
        dynamic->setIncrementSizeSelection(eIncrementSizeSelectionType);
        //用户定义的时间增量
        double UserDefinedTimeIncrement = readDoubleAttribute(h5Group, "UserDefinedTimeIncrement");
        dynamic->setUserDefinedTimeIncrement(UserDefinedTimeIncrement);
        //质量缩放类型
        auto sMassScalingType = readStrAttribute(h5Group, "MassScalingType");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::MassScaling> fitkMSTypeTrafer;
        auto eMassScalingType = fitkMSTypeTrafer.fromString(QString::fromStdString(sMassScalingType), isValid);
        if (!isValid) return false;
        dynamic->setMassScaling(eMassScalingType);

        //质量缩放定义
        if (!h5Group.nameExists("MassScalingObjectives")) return false;
        auto MassScalingObjectivesGroup = h5Group.openGroup("MassScalingObjectives");
        //读取长度
        int NumberOfMassScalingDefinition = readIntAttribute(MassScalingObjectivesGroup, "NumberOfMassScalingDefinition");
        for (int i = 0; i < NumberOfMassScalingDefinition; ++i)
        {
            QString indexName = QString::number(i);

            if (!MassScalingObjectivesGroup.nameExists(indexName.toStdString())) return false;
            auto MassScalingObjectiveGroup = MassScalingObjectivesGroup.openGroup(indexName.toStdString());
            auto massScalingDefinition = dynamic->createMassScalingDefinition();

            auto sMassScalingObjectiveType = readStrAttribute(MassScalingObjectiveGroup, "MassScalingObjectiveType");
            Core::FITKEnumTransfer<Interface::FITkMassScalarEnum::MassScalingObjective> fitkMSOTTypeTrafer;
            auto eMassScalingObjectiveType = fitkMSOTTypeTrafer.fromString(QString::fromStdString(sMassScalingObjectiveType), isValid);
            if (!isValid) return false;
            massScalingDefinition->setMassScalingObjective(eMassScalingObjectiveType);

            auto sMassScalingApplicationRegion = readStrAttribute(MassScalingObjectiveGroup, "MassScalingApplicationRegion");
            Core::FITKEnumTransfer<Interface::FITkMassScalarEnum::MassScalingApplicationRegion> fitkMSARTypeTrafer;
            auto eMassScalingApplicationRegion = fitkMSARTypeTrafer.fromString(QString::fromStdString(sMassScalingApplicationRegion), isValid);
            if (!isValid) return false;
            massScalingDefinition->setMassScalingApplicationRegion(eMassScalingApplicationRegion);

            auto sMassScalingApplicationScale = readStrAttribute(MassScalingObjectiveGroup, "MassScalingApplicationScale");
            Core::FITKEnumTransfer<Interface::FITkMassScalarEnum::MassScalingApplicationScale> fitkMSASTypeTrafer;
            auto eMassScalingApplicationScale = fitkMSASTypeTrafer.fromString(QString::fromStdString(sMassScalingApplicationScale), isValid);
            if (!isValid) return false;
            massScalingDefinition->setMassScalingApplicationScale(eMassScalingApplicationScale);

            //边界位置
            auto location = massScalingDefinition->getLocation();
            if (!location) return false;
            isR &= readBoundaryLocation(location, MassScalingObjectiveGroup);

            bool ScaleByFactor = readIntAttribute(MassScalingObjectiveGroup, "ScaleByFactor");
            massScalingDefinition->setScaleByFactor(ScaleByFactor);

            double ScalerFactor = readDoubleAttribute(MassScalingObjectiveGroup, "ScalerFactor");
            massScalingDefinition->setScalerFactor(ScalerFactor);

            bool ScalerToTargetTimeIncrement = readBoolAttribute(MassScalingObjectiveGroup, "ScalerToTargetTimeIncrement");
            massScalingDefinition->setScalerToTargetTimeIncrement(ScalerToTargetTimeIncrement);

            double TargetIncrement = readDoubleAttribute(MassScalingObjectiveGroup, "TargetIncrement");
            massScalingDefinition->setTargetIncrement(TargetIncrement);

            auto sScaleElementMass = readStrAttribute(MassScalingObjectiveGroup, "ScaleElementMass");
            Core::FITKEnumTransfer<Interface::FITkMassScalarEnum::MassScalingScaleElementMass> fitkMSSETypeTrafer;
            auto eScaleElementMass = fitkMSSETypeTrafer.fromString(QString::fromStdString(sScaleElementMass), isValid);
            if (!isValid) return false;
            massScalingDefinition->setScaleElementMass(eScaleElementMass);

            auto sMassScalingFrequency = readStrAttribute(MassScalingObjectiveGroup, "MassScalingFrequency");
            Core::FITKEnumTransfer<Interface::FITkMassScalarEnum::MassScalingFrequency> fitkMOGTypeTrafer;
            auto eMassScalingFrequency = fitkMOGTypeTrafer.fromString(QString::fromStdString(sMassScalingFrequency), isValid);
            if (!isValid) return false;
            massScalingDefinition->setMassScalingFrequency(eMassScalingFrequency);


            int EveryIncrementNumber = readIntAttribute(MassScalingObjectiveGroup, "EveryIncrementNumber");
            massScalingDefinition->setEveryIncrementNumber(EveryIncrementNumber);

            int NumberOfIntervals = readIntAttribute(MassScalingObjectiveGroup, "NumberOfIntervals");
            massScalingDefinition->setNumberOfInvtervals(NumberOfIntervals);
        }
        double LinearBulkViscosityParameter = readDoubleAttribute(MassScalingObjectivesGroup, "LinearBulkViscosityParameter");
        dynamic->setLinearBulkViscosityParameter(LinearBulkViscosityParameter);

        double QudraticBulkViscosityParameter = readDoubleAttribute(MassScalingObjectivesGroup, "QudraticBulkViscosityParameter");
        dynamic->setQudraticBulkViscosityParameter(QudraticBulkViscosityParameter);

        return isR;
    }

    bool FITKAbaqusHDF5AdaptorStep::readFrequency(Interface::FITKAbaAbstractStep* step, H5::Group& h5Group)
    {
        auto frequency = dynamic_cast<Interface::FITKAbaStepFrequency*>(step);
        if (!frequency) return false;
        bool isValid = false;

        auto sEigenSolver = readStrAttribute(h5Group, "EigenSolver");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::Eigensolver> fitkETypeTrafer;
        auto eEigenSolver = fitkETypeTrafer.fromString(QString::fromStdString(sEigenSolver), isValid);
        if (!isValid) return false;
        frequency->setEigenSolver(eEigenSolver);

        auto sNumberOfEigenvaluesRequstedType = readStrAttribute(h5Group, "NumberOfEigenvaluesRequstedType");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::NumberOfEigenvaluesRequsted> fitkNOERTypeTrafer;
        auto eNumberOfEigenvaluesRequstedType = fitkNOERTypeTrafer.fromString(QString::fromStdString(sNumberOfEigenvaluesRequstedType), isValid);
        if (!isValid) return false;
        frequency->setNumberOfEigenvaluesRequestedType(eNumberOfEigenvaluesRequstedType);



        int NumberOfEigenvaluesRequested = readIntAttribute(h5Group, "NumberOfEigenvaluesRequested");
        frequency->setNumberOfEigenvaluesRequested(NumberOfEigenvaluesRequested);

        auto sAcousticStructuralCouplingWhereApplicableType = readStrAttribute(h5Group, "AcousticStructuralCouplingWhereApplicableType");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::AcousticStructuralCouplingWhereApplicable> fitkASCWTypeTrafer;
        auto eAcousticStructuralCouplingWhereApplicableType = fitkASCWTypeTrafer.fromString(QString::fromStdString(sAcousticStructuralCouplingWhereApplicableType), isValid);
        if (!isValid) return false;
        frequency->setAcousticStructuralCouplingWhereApplicableType(eAcousticStructuralCouplingWhereApplicableType);


        bool FrequencyShift = readBoolAttribute(h5Group, "FrequencyShift");
        frequency->setFrequencyShift(FrequencyShift);

        double FrequencyShiftValue = readDoubleAttribute(h5Group, "FrequencyShiftValue");
        frequency->setFrequencyShiftValue(FrequencyShiftValue);

        bool MinFreqIntrest = readBoolAttribute(h5Group, "MinFreqIntrest");
        frequency->setMinFreqIntrest(MinFreqIntrest);

        double MinFreqInterstValue = readDoubleAttribute(h5Group, "MinFreqInterstValue");
        frequency->setMinFreqInterstValue(MinFreqInterstValue);

        bool MaxFreqInterst = readBoolAttribute(h5Group, "MaxFreqInterst");
        frequency->setMaxFrqInterst(MaxFreqInterst);

        double MaxFreqInterstValue = readDoubleAttribute(h5Group, "MaxFreqInterstValue");
        frequency->setMaxFreqInterstValue(MaxFreqInterstValue);

        auto sBlockSizeType = readStrAttribute(h5Group, "BlockSizeType");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::BlockSize> fitkBSTypeTrafer;
        auto eBlockSizeType = fitkBSTypeTrafer.fromString(QString::fromStdString(sBlockSizeType), isValid);
        if (!isValid) return false;
        frequency->setBlockSizeType(eBlockSizeType);

        int BlockSizeValue = readIntAttribute(h5Group, "BlockSizeValue");
        frequency->setBlockSizeValue(BlockSizeValue);

        auto sMaximumNumberOfBlockLanczosStepType = readStrAttribute(h5Group, "MaximumNumberOfBlockLanczosStepType");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::MaximumNumberOfBlockLanczosStep> fitkMNOBTypeTrafer;
        auto eMaximumNumberOfBlockLanczosStepType = fitkMNOBTypeTrafer.fromString(QString::fromStdString(sMaximumNumberOfBlockLanczosStepType), isValid);
        if (!isValid) return false;
        frequency->setMaximumNumberOfBlockLanczosStepType(eMaximumNumberOfBlockLanczosStepType);



        int MaxNumOfBlockLanczosSteps = readIntAttribute(h5Group, "MaxNumOfBlockLanczosSteps");
        frequency->setMaxNumOfBlockLanczosSteps(MaxNumOfBlockLanczosSteps);

        bool UseSIMBasedLinearDynamicProcedures = readBoolAttribute(h5Group, "UseSIMBasedLinearDynamicProcedures");
        frequency->setUseSIMBasedLinearDynamicProcedures(UseSIMBasedLinearDynamicProcedures);

        bool ProjectDampingOperators = readBoolAttribute(h5Group, "ProjectDampingOperators");
        frequency->setProjectDampingOperators(ProjectDampingOperators);

        bool IncludeResidualModes = readBoolAttribute(h5Group, "IncludeResidualModes");
        frequency->setIncludeResidualModes(IncludeResidualModes);

        int VectorsUsedPerIteration = readIntAttribute(h5Group, "VectorsUsedPerIteration");
        frequency->setVectorsUsedPerIteration(VectorsUsedPerIteration);

        int MaxNumberOfIteration = readIntAttribute(h5Group, "MaxNumberOfIteration");
        frequency->setMaxNumberOfIteration(MaxNumberOfIteration);

        double AcousticRangeFactor = readDoubleAttribute(h5Group, "AcousticRangeFactor");
        frequency->setAcousticRangeFactor(AcousticRangeFactor);

        auto sMatrixStorage = readStrAttribute(h5Group, "MatrixStorage");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::MatrixStorage> fitkMSTypeTrafer;
        auto eMatrixStorage = fitkMSTypeTrafer.fromString(QString::fromStdString(sMatrixStorage), isValid);
        if (!isValid) return false;
        frequency->setMatrixStorage(eMatrixStorage);


        auto sNormalizeEnginevectors = readStrAttribute(h5Group, "NormalizeEnginevectors");
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::NormalizeEnginevectors> fitkNETypeTrafer;
        auto eIncrementType = fitkNETypeTrafer.fromString(QString::fromStdString(sNormalizeEnginevectors), isValid);
        if (!isValid) return false;
        frequency->setNormalizeEnginevectors(eIncrementType);


        return true;
    }

    bool FITKAbaqusHDF5AdaptorStep::writeStep(Interface::FITKAbaAbstractStep* step, H5::Group& h5Group)
    {
        if (!step) return false;
        bool isW = true;
        bool isValid = false;

        std::string groupName = createParentAttribute(step, h5Group);
        if (groupName.empty())return false;

        auto stepGroup = h5Group.createGroup(groupName);
        //type
        auto stepType = step->getStepType();

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::FITKAbaStepType> fitkSTTypeTrafer;
        auto Type = fitkSTTypeTrafer.toStrting(stepType, isValid);
        if (!isValid) return false;
        writeStrAttribute(stepGroup, "Type", Type.toStdString());

        //decription
        QString Decription = step->getDecription();
        writeStrAttribute(stepGroup, "Decription", Decription.toStdString());
        //Nlgeom
        bool Nlgeom = step->getNlgeom();
        writeBoolAttribute(stepGroup, "Nlgeom", &Nlgeom);
        //Time
        double Time = step->getTime();
        writeDoubleAttribute(stepGroup, "Time", &Time);
        //Active
        bool Active = step->isActive();
        writeBoolAttribute(stepGroup, "Active", &Active);
        //RestartWriteFrequency
        int RestartWriteFrequency = step->getRestartWriteFrequency();
        writeIntAttribute(stepGroup, "RestartWriteFrequency", &RestartWriteFrequency);
        //RestartWriteIntervals
        int RestartWriteIntervals = step->getRestartWriteIntervals();
        writeIntAttribute(stepGroup, "RestartWriteIntervals", &RestartWriteIntervals);
        //OverlayState
        bool OverlayState = step->getOverlayState();
        writeBoolAttribute(stepGroup, "OverlayState", &OverlayState);
        //TimeMarkState
        bool TimeMarkState = step->getTimeMarkState();
        writeBoolAttribute(stepGroup, "TimeMarkState", &TimeMarkState);

        if (stepType == Interface::FITKAbaAbstractStep::FITKAbaStepType::GeneralStatic)
        {
            isW &= writeStatic(step, stepGroup);
        }
        else if (stepType == Interface::FITKAbaAbstractStep::FITKAbaStepType::DynamicExplicit)
        {
            isW &= writeDynamic(step, stepGroup);
        }
        else if (stepType == Interface::FITKAbaAbstractStep::FITKAbaStepType::Frequency)
        {
            isW &= writeFrequency(step, stepGroup);
        }
        else if (stepType == Interface::FITKAbaAbstractStep::FITKAbaStepType::Init)
        {

        }
        else
        {
            return false;
        }
        //写出基础信息
        isW &= writeNDataObject(step, stepGroup);

        return isW;
    }

    bool FITKAbaqusHDF5AdaptorStep::writeStatic(Interface::FITKAbaAbstractStep* step, H5::Group& h5Group)
    {
        auto generalStetic = dynamic_cast<Interface::FITKAbaStepGeneralStatic*>(step);
        if (!generalStetic) return false;
        bool isValid = false;

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::TimeIncrementType> fitkTTTypeTrafer;
        auto IncrementType = fitkTTTypeTrafer.toStrting(generalStetic->getIncrementType(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "IncrementType", IncrementType.toStdString());

        int MaximumNumberOfIncrements = generalStetic->getMaximumNumberOfIncrements();
        writeIntAttribute(h5Group, "MaximumNumberOfIncrements", &MaximumNumberOfIncrements);

        double InitIncrementSize = generalStetic->getInitIncrementSize();
        writeDoubleAttribute(h5Group, "InitIncrementSize", &InitIncrementSize);

        double MinIncrementSize = generalStetic->getMinIncrementSize();
        writeDoubleAttribute(h5Group, "MinIncrementSize", &MinIncrementSize);

        double MaxIncrementSize = generalStetic->getMaxIncrementSize();
        writeDoubleAttribute(h5Group, "MaxIncrementSize", &MaxIncrementSize);

        double FixedIncrementSize = generalStetic->getFixedIncrementSize();
        writeDoubleAttribute(h5Group, "FixedIncrementSize", &FixedIncrementSize);

        return true;
    }

    bool FITKAbaqusHDF5AdaptorStep::writeDynamic(Interface::FITKAbaAbstractStep* step, H5::Group& h5Group)
    {
        auto dynamic = dynamic_cast<Interface::FITKAbaStepDynamicExplicit*>(step);
        if (!dynamic) return false;
        bool isW = true;
        bool isValid = false;

        bool IncludeAdiabaticHeatingEffects = dynamic->getIncludeAdiabaticHeatingEffects();
        writeBoolAttribute(h5Group, "IncludeAdiabaticHeatingEffects", &IncludeAdiabaticHeatingEffects);

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::TimeIncrementType> fitkTITTypeTrafer;
        auto IncrementType = fitkTITTypeTrafer.toStrting(dynamic->getIncrementType(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "IncrementType", IncrementType.toStdString());

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::StableIncrementEstimator> fitkSIETypeTrafer;
        auto StableIncrementEstimatorType = fitkSIETypeTrafer.toStrting(dynamic->getStableIncrementEstimator(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "StableIncrementEstimatorType", StableIncrementEstimatorType.toStdString());

        bool ImproveDtMethod = dynamic->getImproveDtMethod();
        writeBoolAttribute(h5Group, "ImproveDtMethod", &ImproveDtMethod);

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::MaxTimeIncrement> fitkMTITypeTrafer;
        auto MaxTimeIncrementType = fitkMTITypeTrafer.toStrting(dynamic->getMaxTimeIncrement(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "MaxTimeIncrementType", MaxTimeIncrementType.toStdString());

        double MaxTimeIncrementValue = dynamic->getMaxTimeIncrementValue();
        writeDoubleAttribute(h5Group, "MaxTimeIncrementValue", &MaxTimeIncrementValue);

        double TimeScalingFactor = dynamic->getTimeScalingFactor();
        writeDoubleAttribute(h5Group, "TimeScalingFactor", &TimeScalingFactor);

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::IncrementSizeSelection> fitkISSTypeTrafer;
        auto IncrementSizeSelectionType = fitkISSTypeTrafer.toStrting(dynamic->getIncrementSizeSelection(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "IncrementSizeSelectionType", IncrementSizeSelectionType.toStdString());

        double UserDefinedTimeIncrement = dynamic->getUserDefinedTimeIncrement();
        writeDoubleAttribute(h5Group, "UserDefinedTimeIncrement", &UserDefinedTimeIncrement);

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::MassScaling> fitkMSTypeTrafer;
        auto MassScalingType = fitkMSTypeTrafer.toStrting(dynamic->getMassScaling(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "MassScalingType", MassScalingType.toStdString());

        auto MassScalingObjectivesGroup = h5Group.createGroup("MassScalingObjectives");
        int massNumber = dynamic->getNumberOfMassScalingDefinition();
        //写出长度
        writeIntAttribute(MassScalingObjectivesGroup, "NumberOfMassScalingDefinition", &massNumber);
        for (int i = 0; i < massNumber; ++i)
        {
            auto massScaling = dynamic->getMassScalingDefinition(i);
            QString indexName = QString::number(i);
            auto MassScalingObjectiveGroup = MassScalingObjectivesGroup.createGroup(indexName.toStdString());

            //枚举转换字符
            Core::FITKEnumTransfer<Interface::FITkMassScalarEnum::MassScalingObjective> fitkMSOTypeTrafer;
            auto MassScalingObjectiveType = fitkMSOTypeTrafer.toStrting(massScaling->getMassScalingObjectvie(), isValid);
            if (!isValid) return false;
            writeStrAttribute(MassScalingObjectiveGroup, "MassScalingObjectiveType", MassScalingObjectiveType.toStdString());

            //枚举转换字符
            Core::FITKEnumTransfer<Interface::FITkMassScalarEnum::MassScalingApplicationRegion> fitkMSIRTypeTrafer;
            auto MassScalingApplicationRegion = fitkMSIRTypeTrafer.toStrting(massScaling->getMassScalingApplicationRegion(), isValid);
            if (!isValid) return false;
            writeStrAttribute(MassScalingObjectiveGroup, "MassScalingApplicationRegion", MassScalingApplicationRegion.toStdString());

            //枚举转换字符
            Core::FITKEnumTransfer<Interface::FITkMassScalarEnum::MassScalingApplicationScale> fitkMSARTypeTrafer;
            auto MassScalingApplicationScale = fitkMSARTypeTrafer.toStrting(massScaling->getMassScalingApplicationScale(), isValid);
            if (!isValid) return false;
            writeStrAttribute(MassScalingObjectiveGroup, "MassScalingApplicationScale", MassScalingApplicationScale.toStdString());

            //边界位置
            auto location = massScaling->getLocation();
            if (!location) return false;
            isW &= writeBoundaryLocation(location, MassScalingObjectiveGroup);

            bool ScaleByFactor = massScaling->getScaleByFactor();
            writeIntAttribute(MassScalingObjectiveGroup, "ScaleByFactor", &ScaleByFactor);

            double ScalerFactor = massScaling->getScalerFactor();
            writeDoubleAttribute(MassScalingObjectiveGroup, "ScalerFactor", &ScalerFactor);

            bool ScalerToTargetTimeIncrement = massScaling->getScalerToTargetTimeIncrement();
            writeBoolAttribute(MassScalingObjectiveGroup, "ScalerToTargetTimeIncrement", &ScalerToTargetTimeIncrement);

            double TargetIncrement = massScaling->getTargetIncrement();
            writeDoubleAttribute(MassScalingObjectiveGroup, "TargetIncrement", &TargetIncrement);

            //枚举转换字符
            Core::FITKEnumTransfer<Interface::FITkMassScalarEnum::MassScalingScaleElementMass> fitkMSSETypeTrafer;
            auto ScaleElementMass = fitkMSSETypeTrafer.toStrting(massScaling->getScaleElementMass(), isValid);
            if (!isValid) return false;
            writeStrAttribute(MassScalingObjectiveGroup, "ScaleElementMass", ScaleElementMass.toStdString());

            //枚举转换字符
            Core::FITKEnumTransfer<Interface::FITkMassScalarEnum::MassScalingFrequency> fitkMSFTypeTrafer;
            auto MassScalingFrequency = fitkMSFTypeTrafer.toStrting(massScaling->getMassScalingFrequency(), isValid);
            if (!isValid) return false;
            writeStrAttribute(MassScalingObjectiveGroup, "MassScalingFrequency", MassScalingFrequency.toStdString());


            int EveryIncrementNumber = massScaling->getEveryIncrementNumber();
            writeIntAttribute(MassScalingObjectiveGroup, "EveryIncrementNumber", &EveryIncrementNumber);

            int NumberOfIntervals = massScaling->getNumberOfIntervals();
            writeIntAttribute(MassScalingObjectiveGroup, "NumberOfIntervals", &NumberOfIntervals);
        }
        double LinearBulkViscosityParameter = dynamic->getLinearBulkViscosityParameter();
        writeDoubleAttribute(MassScalingObjectivesGroup, "LinearBulkViscosityParameter", &LinearBulkViscosityParameter);

        double QudraticBulkViscosityParameter = dynamic->getQudraticBulkViscosityParameter();
        writeDoubleAttribute(MassScalingObjectivesGroup, "QudraticBulkViscosityParameter", &QudraticBulkViscosityParameter);

        return isW;
    }

    bool FITKAbaqusHDF5AdaptorStep::writeFrequency(Interface::FITKAbaAbstractStep* step, H5::Group& h5Group)
    {
        auto frequency = dynamic_cast<Interface::FITKAbaStepFrequency*>(step);
        if (!frequency) return false;

        bool isValid = false;
        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::Eigensolver> fitkIEigenSolverTypeTrafer;
        auto EigenSolver = fitkIEigenSolverTypeTrafer.toStrting(frequency->getEigenSolver(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "EigenSolver", EigenSolver.toStdString());

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::NumberOfEigenvaluesRequsted> fitkNOTypeTrafer;
        auto NumberOfEigenvaluesRequstedType = fitkNOTypeTrafer.toStrting(frequency->getNumberOfEigenvaluesRequstedType(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "NumberOfEigenvaluesRequstedType", NumberOfEigenvaluesRequstedType.toStdString());

        int NumberOfEigenvaluesRequested = frequency->getNumberOfEigenvaluesRequested();
        writeIntAttribute(h5Group, "NumberOfEigenvaluesRequested", &NumberOfEigenvaluesRequested);

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::AcousticStructuralCouplingWhereApplicable> fitkASTypeTrafer;
        auto AcousticStructuralCouplingWhereApplicableType = fitkASTypeTrafer.toStrting(frequency->getAcousticStructuralCouplingWhereApplicableType(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "AcousticStructuralCouplingWhereApplicableType", AcousticStructuralCouplingWhereApplicableType.toStdString());

        bool FrequencyShift = frequency->getFrequencyShift();
        writeBoolAttribute(h5Group, "FrequencyShift", &FrequencyShift);

        double FrequencyShiftValue = frequency->getFrequencyShiftValue();
        writeDoubleAttribute(h5Group, "FrequencyShiftValue", &FrequencyShiftValue);

        bool MinFreqIntrest = frequency->getMinFreqIntrest();
        writeBoolAttribute(h5Group, "MinFreqIntrest", &MinFreqIntrest);

        double MinFreqInterstValue = frequency->getMinFreqInterstValue();
        writeDoubleAttribute(h5Group, "MinFreqInterstValue", &MinFreqInterstValue);

        bool MaxFreqInterst = frequency->getMaxFreqInterst();
        writeBoolAttribute(h5Group, "MaxFreqInterst", &MaxFreqInterst);

        double MaxFreqInterstValue = frequency->getMaxFreqInterstValue();
        writeDoubleAttribute(h5Group, "MaxFreqInterstValue", &MaxFreqInterstValue);

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::BlockSize> fitkBSTypeTrafer;
        auto BlockSizeType = fitkBSTypeTrafer.toStrting(frequency->getBlockSizeType(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "BlockSizeType", BlockSizeType.toStdString());


        int BlockSizeValue = frequency->getBlockSizeValue();
        writeIntAttribute(h5Group, "BlockSizeValue", &BlockSizeValue);

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::MaximumNumberOfBlockLanczosStep> fitkMNTypeTrafer;
        auto MaximumNumberOfBlockLanczosStepType = fitkMNTypeTrafer.toStrting(frequency->getMaximumNumberOfBlockLanczosStepType(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "MaximumNumberOfBlockLanczosStepType", MaximumNumberOfBlockLanczosStepType.toStdString());

        int MaxNumOfBlockLanczosSteps = frequency->getMaxNumOfBlockLanczosSteps();
        writeIntAttribute(h5Group, "MaxNumOfBlockLanczosSteps", &MaxNumOfBlockLanczosSteps);

        bool UseSIMBasedLinearDynamicProcedures = frequency->getUseSIMBasedLinearDynamicProcedures();
        writeBoolAttribute(h5Group, "UseSIMBasedLinearDynamicProcedures", &UseSIMBasedLinearDynamicProcedures);

        bool ProjectDampingOperators = frequency->getProjectDampingOperators();
        writeBoolAttribute(h5Group, "ProjectDampingOperators", &ProjectDampingOperators);

        bool IncludeResidualModes = frequency->getIncludeResidualModes();
        writeBoolAttribute(h5Group, "IncludeResidualModes", &IncludeResidualModes);

        int VectorsUsedPerIteration = frequency->getVectorsUsedPerIteration();
        writeIntAttribute(h5Group, "VectorsUsedPerIteration", &VectorsUsedPerIteration);

        int MaxNumberOfIteration = frequency->getMaxNumberOfIteration();
        writeIntAttribute(h5Group, "MaxNumberOfIteration", &MaxNumberOfIteration);

        double AcousticRangeFactor = frequency->getAcousticRangeFactor();
        writeDoubleAttribute(h5Group, "AcousticRangeFactor", &AcousticRangeFactor);

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::MatrixStorage> fitkMSTypeTrafer;
        auto MatrixStorage = fitkMSTypeTrafer.toStrting(frequency->getMatrixStorage(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "MatrixStorage", MatrixStorage.toStdString());

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractStep::NormalizeEnginevectors> fitkNETypeTrafer;
        auto NormalizeEnginevectors = fitkNETypeTrafer.toStrting(frequency->getNormalizeEnginevectors(), isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "NormalizeEnginevectors", NormalizeEnginevectors.toStdString());

        return true;
    }

    bool FITKAbaqusHDF5AdaptorStep::readBoundaryLocation(Interface::FITKBoundaryLocation* boundLocation, H5::Group& h5Group)
    {
        if (!boundLocation) return false;
        //边界位置读取
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKInterfaceHDF5AdaptorBoundaryLocation>("HDF5", "Interface::FITKBoundaryLocation");
        if (adaptor == nullptr)
        {
            return false;
        }
        adaptor->setDataObject(boundLocation);
        adaptor->setFileReader(_reader);
        adaptor->setH5GroupData(h5Group);
        bool isR = adaptor->adaptR();
        delete adaptor;
        return isR;
    }

    bool FITKAbaqusHDF5AdaptorStep::writeBoundaryLocation(Interface::FITKBoundaryLocation* boundLocation, H5::Group& h5Group)
    {
        if (!boundLocation) return false;

        //边界位置写出
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKInterfaceHDF5AdaptorBoundaryLocation>("HDF5", "Interface::FITKBoundaryLocation");
        if (adaptor == nullptr)
        {
            return false;
        }
        adaptor->setDataObject(boundLocation);
        adaptor->setFileWriter(_writer);
        adaptor->setH5GroupData(h5Group);
        bool isW = adaptor->adaptW();
        delete adaptor;
        return isW;
    }

}
